import { useActionMode } from '@renderer/stores/actionMode'
import { useActiveObject } from '@renderer/stores/activeObject'
import { useViewportStore } from '@renderer/stores/viewport'
import useEditor from '@renderer/utils/useEditor'
import { storeToRefs } from 'pinia'
import { Plane, Raycaster, Vector2, Vector3 } from 'three'
import { watchEffect, ref } from 'vue'
import BContextmenu from '@renderer/components/b-contextmenu.vue'

export default function () {
  const viewportStore = useViewportStore()
  const { publicGroup, canvas, camera, css2DRenderer, transformControls } =
    storeToRefs(viewportStore)

  const activeObjectStore = useActiveObject()
  const { activeVO } = storeToRefs(activeObjectStore)
  const actionModeStore = useActionMode()
  const { currentMode } = storeToRefs(actionModeStore)
  const { createRoadway } = useEditor()
  let isRaycasterEnabled = true
  const mouse = new Vector2()
  const raycaster = new Raycaster()
  raycaster.layers.set(0)

  // 创建contextMenu的ref
  const contextMenuRef = ref<InstanceType<typeof BContextmenu> | null>(null)
  function setContextMenuRef(val) {
    contextMenuRef.value = val
  }

  watchEffect(() => {
    if (canvas.value && css2DRenderer.value && canvas.value) {
      css2DRenderer.value.domElement.addEventListener('mousemove', (e) => {
        if (canvas.value && camera.value && activeVO.value) {
          const { clientWidth, clientHeight } = canvas.value
          mouse.x = (e.offsetX / clientWidth) * 2 - 1
          mouse.y = -(e.offsetY / clientHeight) * 2 + 1
          raycaster.setFromCamera(mouse, camera.value)

          // 将鼠标位置转换为三维世界坐标
          if (currentMode.value === 'createdRoadway') {
            const pos = activeVO.value.position
            const intersects = getWorldPositionAtFixedY(pos.y)
            if (intersects) {
              createRoadway(`绘制巷道-${activeVO.value.uuid}`, [
                intersects,
                activeVO.value.position
              ])
            }
          } else if (currentMode.value === 'mergedRoadway') {
            console.log('mergedRoadway')
          }
        }
      })
      // 选中元素
      css2DRenderer.value.domElement.addEventListener('mouseup', (e) => {
        if (canvas.value) {
          const { clientWidth, clientHeight } = canvas.value
          if (e.button === 0) {
            mouse.x = (e.offsetX / clientWidth) * 2 - 1
            mouse.y = -(e.offsetY / clientHeight) * 2 + 1
            if (publicGroup.value && camera.value && isRaycasterEnabled) {
              raycaster.setFromCamera(mouse, camera.value)
              const intersects = raycaster.intersectObjects(publicGroup.value.children)
              if (intersects[0] && intersects[0].object.visible) {
                activeObjectStore.setActiveVO(intersects[0].object)
              } else {
                activeObjectStore.setActiveVO(undefined)
              }
            }
            isRaycasterEnabled = true
          }
        }
      })

      // 鼠标右键
      css2DRenderer.value.domElement.addEventListener('contextmenu', (e) => {
        e.preventDefault() // 阻止默认右键菜单
        if (canvas.value) {
          const { clientWidth, clientHeight } = canvas.value
          mouse.x = (e.offsetX / clientWidth) * 2 - 1
          mouse.y = -(e.offsetY / clientHeight) * 2 + 1
          if (publicGroup.value && camera.value && isRaycasterEnabled) {
            raycaster.setFromCamera(mouse, camera.value)
            const intersects = raycaster.intersectObjects(publicGroup.value.children)
            if (intersects[0] && intersects[0].object.visible) {
              // 显示自定义右键菜单
              contextMenuRef.value?.show(e.clientX, e.clientY, intersects[0])
            } else {
              contextMenuRef.value?.hide()
            }
          }
        }
      })

      // 点击其他地方时隐藏右键菜单
      document.addEventListener('click', () => {
        contextMenuRef.value?.hide()
      })

      // 进行变换时不切换选中的物体
      transformControls.value?.addEventListener('objectChange', function () {
        isRaycasterEnabled = false
      })
    }
  })
  // 获取鼠标位置在固定 Y 值下的世界坐标
  function getWorldPositionAtFixedY(fixedY) {
    if (camera.value) {
      // 创建一个与 Y = fixedY 平行的平面
      const plane = new Plane(new Vector3(0, 1, 0), -fixedY)

      // 计算射线与平面的交点
      const intersectPoint = new Vector3()
      const ray = raycaster.ray
      if (ray.intersectPlane(plane, intersectPoint)) {
        return intersectPoint
      }
      return null
    }
    return null
  }

  return {
    setContextMenuRef
  }
}
